package org.d8s.magicapi.plugin.interceptor;

import org.d8s.magicapi.util.HttpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;
import org.ssssssss.magicapi.interceptor.RequestInterceptor;
import org.ssssssss.magicapi.model.ApiInfo;
import org.ssssssss.magicapi.model.JsonBean;
import org.ssssssss.script.MagicScriptContext;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static org.d8s.magicapi.util.EncryptConstants.START_PLUGIN_LOG_MSG;

/**
 * IP白名单，黑名单
 *
 * @author 冰点
 * @date 2021-5-20 15:14:59
 */
@Component
@ConditionalOnProperty(prefix = "magic-plugin.iplimit", name = "enable", havingValue = "true", matchIfMissing = false)
public class IpLimitRequestInterceptor implements RequestInterceptor {

    private static final Logger log = LoggerFactory.getLogger(IpLimitRequestInterceptor.class);
    /**
     * 白名单
     */
    @Value("magic-plugin.iplimit.whitelist")
    private String whitelist;
    /**
     * 黑名单
     */
    @Value("magic-plugin.iplimit.blacklist")
    private String blacklist;

    @PostConstruct
    public void initIpLimitRequestInterceptor() {
        log.info(START_PLUGIN_LOG_MSG, "IP白名单", "magic-plugin.iplimit.enable=false", "magic-plugin.iplimit.whitelist=ip地址逗号分隔");
    }

    /**
     * 接口请求之前
     *
     * @param info    接口信息
     * @param context 脚本变量信息
     */
    @Override
    public Object preHandle(ApiInfo info, MagicScriptContext context, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String ip = HttpUtil.getIpAddr(request);
        Boolean isLimit = checkIpIsLimit(ip);
        if (isLimit) {
            return new JsonBean(100, String.format("ip:[%s]请求URL:[%s]，为非法请求，请检查IP限制名单", ip, info.getPath()));
        }
        return null;
    }

    /**
     * 接口执行之后
     *
     * @param info    接口信息
     * @param context 变量信息
     * @param value   即将要返回到页面的值
     */
    @Override
    public Object postHandle(ApiInfo info, MagicScriptContext context, Object value, HttpServletRequest request, HttpServletResponse response) throws Exception {
        log.debug("{} 执行完毕，返回结果:{}", info.getName(), value);
        return null;
    }

    /**
     * @param ipAddr
     * @return
     */
    private Boolean checkIpIsLimit(String ipAddr) {
        if (blacklist.contains(ipAddr)) {
            return true;
        } else if (!blacklist.isEmpty() && !blacklist.contains(ipAddr)) {
            return true;
        }
        return false;
    }

}
